#include "glfw.hh"
#include "../utils/journal.hh"
#include <stdexcept>
#include <string>

namespace ngintoy
{
    namespace platform
    {
        namespace {
            static platform::registrar<glfw> _{"glfw"};

            using jn = utils::journal;
            using namespace std::literals;

            void error_callback(int /*error*/, const char* msg)
            {
                throw std::runtime_error{"glfw platform: "s + msg};
            }
        }

        glfw::glfw(config &)
        {
            jn::begin() << "glfw platform";

            glfwSetErrorCallback(error_callback);
            glfwInit();
        }

        glfw::~glfw()
        {
            jn::end() << "glfw platform";

            glfwTerminate();
        }

        double glfw::now()
        {
            return glfwGetTime();
        }

        bool glfw::poll()
        {
            if (!win) throw std::runtime_error{"calling make_context required"};

            glfwSwapBuffers(win);
            glfwPollEvents();

            return !glfwWindowShouldClose(win);
        }

        void glfw::make_context(int major_ver, int minor_ver)
        {
            auto info = jn::info(" glfw");
            info << "make context";

            info << "  - OpenGL " + std::to_string(major_ver) + "." + std::to_string(minor_ver);
            glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, major_ver);
            glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, minor_ver);
            if (major_ver >= 3) {
                glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true);
                info << "  - forward compatible";
                if (!(major_ver == 3 && minor_ver < 2)) {
                    info << "  - core profile";
                    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
                }
            }

#ifdef RELEASE
            jn::warn("CRASH") << "  - no-error context (SHOULD CRASH)";
            glfwWindowHint(GLFW_CONTEXT_NO_ERROR, true);
#else
            info << "  - debug context";
            glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
#endif

            win = glfwCreateWindow(640, 480, "ngintoy", nullptr, nullptr);
            glfwMakeContextCurrent(win);
            glfwSwapInterval(1);
        }
    }
}

